Skip to content

Add Classloader precheck to expensive matchers.#1283

Merged
tylerbenson merged 2 commits into
masterfrom
tyler/classloader-precheck
Mar 4, 2020
Merged

Add Classloader precheck to expensive matchers.#1283
tylerbenson merged 2 commits into
masterfrom
tyler/classloader-precheck

Conversation

@tylerbenson
Copy link
Copy Markdown
Contributor

Benchmark results:

Benchmark                                                             Mode  Cnt   Score   Error  Units
ClassRetransformingBenchmark.WithAgent.testTracedRetransform          avgt       21.933          ms/op
ClassRetransformingBenchmark.WithAgent.testUntracedRetransform        avgt        6.171          ms/op
ClassRetransformingBenchmark.WithAgentMaster.testTracedRetransform    avgt       22.129          ms/op
ClassRetransformingBenchmark.WithAgentMaster.testUntracedRetransform  avgt        6.517          ms/op
ClassRetransformingBenchmark.testTracedRetransform                    avgt        0.876          ms/op
ClassRetransformingBenchmark.testUntracedRetransform                  avgt        0.867          ms/op

I also saw a small improvement in application startup time.

Benchmark results:
```
Benchmark                                                             Mode  Cnt   Score   Error  Units
ClassRetransformingBenchmark.WithAgent.testTracedRetransform          avgt       21.933          ms/op
ClassRetransformingBenchmark.WithAgent.testUntracedRetransform        avgt        6.171          ms/op
ClassRetransformingBenchmark.WithAgentMaster.testTracedRetransform    avgt       22.129          ms/op
ClassRetransformingBenchmark.WithAgentMaster.testUntracedRetransform  avgt        6.517          ms/op
ClassRetransformingBenchmark.testTracedRetransform                    avgt        0.876          ms/op
ClassRetransformingBenchmark.testUntracedRetransform                  avgt        0.867          ms/op
```

I also saw a small improvement in application startup time.
@tylerbenson tylerbenson requested a review from a team as a code owner March 3, 2020 18:30
Copy link
Copy Markdown
Contributor

@randomanderson randomanderson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

2 comments:

  • It seems like not(classLoaderHasNoResources(...)) is the default so maybe the matcher itself should be inverted
  • I wish this could be added automagically at compile time when implementsInterface is detected. I'll keep it in mind for the future 📓

@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("com/amazonaws/AmazonWebServiceRequest.class"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The double negative is a bit hard to read. I think a utility method would help clarity greatly.

@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/hibernate/Session.class"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One observation from the field injection optimization. Often our classLoaderMatchers are really more aim at matching a library or an API, but we don't really have that as a concept in the code.

I think this change also suggest that we should have some notion of a Library go which Instrumenters refer.

@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
return classLoaderHasNoResources("redis/clients/jedis/commands/ProtocolCommand.class");
return classLoaderHasNoResources("redis/clients/jedis/commands/ProtocolCommand.class")
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this speaks to the fact that we should make a classLoaderHasResources. Then this could be a single matcher.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it would be nice to have a comment here explaining what's going on

Copy link
Copy Markdown
Contributor

@dougqh dougqh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I do have some quibbles with the details, overall, I like the change. It gives us a cheap way to effectively check whether or not an Instrumenter needs to be activated which is nice.

I'm wondering if we'd get a bit more by caching and/or introducing a first class of concept of a Library, so that we can further reduce the number of Matchers being checked.

I do have one theoretical concern about whether checking getResource is really a reliable way to check for existence of a class. I don't believe getResource traverses through parent loaders (maybe the Matcher accounts for that) and can be overridden separately findClass.

However, I think that complaint is somewhat fundamental in how ByteBuddy works already. I think that's an issue we need to revisit, but not necessarily as part of this PR.

@tylerbenson
Copy link
Copy Markdown
Contributor Author

I agree with the complaints about the double negative, though I was trying to get something out quickly. I think this offers a decent amount of improvement, so I'm going to merge as is, and we can plan for future iterations.

@tylerbenson tylerbenson merged commit 95534b7 into master Mar 4, 2020
@tylerbenson tylerbenson deleted the tyler/classloader-precheck branch March 4, 2020 04:39
@Override
public ElementMatcher<ClassLoader> classLoaderMatcher() {
// Optimization for expensive typeMatcher.
return not(classLoaderHasNoResources("org/apache/http/nio/client/HttpAsyncClient.class"));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double negatives are somewhat hard to read

@tylerbenson tylerbenson added this to the 0.45.0 milestone Mar 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants